using System.Collections.ObjectModel;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using demo001.Config;
using demo001.Models;

namespace demo001.Services
{
    /// <summary>
    /// 视频服务类
    /// 处理视频相关的业务逻辑，包括视频搜索、订阅管理、本地存储等功能
    /// 作为应用程序的核心服务之一，管理视频内容的获取和本地管理
    /// </summary>
    public class VideoService
    {
        /// <summary>
        /// API服务实例，用于与后端服务器通信
        /// </summary>
        private readonly ApiService _apiService;
        /// <summary>
        /// 订阅信息文件的本地存储路径
        /// </summary>
        private readonly string _subscriptionsFilePath;

        /// <summary>
        /// 已订阅视频的集合
        /// 使用ObservableCollection实现数据绑定
        /// </summary>
        private ObservableCollection<VideoViewModel> _subscribedVideos = new ObservableCollection<VideoViewModel>();

        /// <summary>
        /// 已订阅视频集合的公开访问属性
        /// 提供对订阅视频的只读访问
        /// </summary>
        public ObservableCollection<VideoViewModel> SubscribedVideos => _subscribedVideos;

        /// <summary>
        /// 构造函数
        /// 初始化服务，设置存储路径，加载已订阅视频
        /// </summary>
        public VideoService()
        {
            _apiService = new ApiService();
            // 确保存储目录存在
            string appDataPath = FileSystem.AppDataDirectory;
            string subscriptionsDir = Path.Combine(appDataPath, "Subscriptions");
            Directory.CreateDirectory(subscriptionsDir);
            
            // 设置订阅信息文件路径
            _subscriptionsFilePath = Path.Combine(subscriptionsDir, "subscriptions.json");
            
            // 加载已订阅视频
            LoadSubscribedVideos();
        }

        /// <summary>
        /// 搜索视频
        /// 根据关键词从服务器搜索视频内容
        /// </summary>
        /// <param name="query">搜索关键词</param>
        /// <param name="page">页码，默认为1</param>
        /// <param name="pageSize">每页数量，默认为10</param>
        /// <returns>视频列表</returns>
        public async Task<List<VideoViewModel>> SearchVideosAsync(string query, int page = 1, int pageSize = 10)
        {
            try
            {
                // 打印详细的调试信息
                System.Diagnostics.Debug.WriteLine($"SearchVideosAsync 调用开始");
                System.Diagnostics.Debug.WriteLine($"查询参数:");
                System.Diagnostics.Debug.WriteLine($"query: {query}");
                System.Diagnostics.Debug.WriteLine($"page: {page}");
                System.Diagnostics.Debug.WriteLine($"pageSize: {pageSize}");

                // 获取 API 配置的基础 URL
                var baseUrl = ApiConfig.Video.Search.GetFullUrl();
                System.Diagnostics.Debug.WriteLine($"基础 URL: {baseUrl}");

                // 手动构建完整的 URL
                var fullUrl = $"{baseUrl}?query={Uri.EscapeDataString(query)}&page={page}&pageSize={pageSize}";
                System.Diagnostics.Debug.WriteLine($"完整 URL: {fullUrl}");

                var _httpClient = HttpClientFactory.GetClient();
                // 直接使用 HttpClient 发送请求
                var response = await _httpClient.GetAsync(fullUrl);

                // 打印响应状态码
                System.Diagnostics.Debug.WriteLine($"响应状态码: {response.StatusCode}");

                // 检查响应是否成功
                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    System.Diagnostics.Debug.WriteLine($"请求失败。错误内容: {errorContent}");
                    return new List<VideoViewModel>();
                }

                // 读取响应内容
                var content = await response.Content.ReadAsStringAsync();
                System.Diagnostics.Debug.WriteLine($"响应内容: {content}");

                // 反序列化响应
                var result = System.Text.Json.JsonSerializer.Deserialize<PagedResult<VideoDto>>(
                    content, 
                    new System.Text.Json.JsonSerializerOptions 
                    { 
                        PropertyNameCaseInsensitive = true 
                    });

                if (result != null && result.Items != null)
                {
                    // 转换 VideoDto 到 VideoViewModel
                    var videoViewModels = new List<VideoViewModel>();
                    
                    foreach (var dto in result.Items)
                    {
                        var viewModel = new VideoViewModel
                        {
                            VideoId = dto.VideoId,
                            Title = dto.Title,
                            Duration = dto.Duration,
                            VideoUrl = dto.VideoUrl,
                            // 处理可空的 FileSize
                            FileSize = dto.FileSize ?? 0, // 如果为 null 则默认为 0
                            CreatedDate = dto.CreatedDate,
                            UpdatedDate = dto.UpdatedDate
                        };

                        // 单独处理 IsSubscribed
                        viewModel.IsSubscribed = IsVideoSubscribed(dto.VideoId);

                        videoViewModels.Add(viewModel);
                    }

                    return videoViewModels;
                }
                return new List<VideoViewModel>();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"搜索视频出错: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
                return new List<VideoViewModel>();
            }
        }

        public async Task<PagedResult<VideoDto>> SearchVideosAsync2(string query, int page = 1, int pageSize = 10)
        {
            try
            {
                var url = $"{ApiConfig.Video.Search.GetFullUrl()}?query={Uri.EscapeDataString(query)}&page={page}&pageSize={pageSize}";
                var _httpClient = HttpClientFactory.GetClient();
                var response = await _httpClient.GetAsync(url);

                if (response.IsSuccessStatusCode)
                {
                    return await response.Content.ReadFromJsonAsync<PagedResult<VideoDto>>();
                }

                throw new Exception($"搜索视频失败: {response.StatusCode}");
            }
            catch (Exception ex)
            {
                throw new Exception($"搜索视频时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取视频详情
        /// 根据视频ID获取单个视频的详细信息
        /// </summary>
        /// <param name="videoId">视频ID</param>
        /// <returns>视频详情对象，如果获取失败则返回null</returns>
        public async Task<VideoViewModel?> GetVideoAsync(long videoId)
        {
            try
            {
                var parameters = new Dictionary<string, string> { { "id", videoId.ToString() } };
                var video = await _apiService.GetAsync<VideoViewModel>(
                    ApiConfig.Video.GetVideo,
                    parameters);
                
                if (video != null)
                {
                    video.IsSubscribed = IsVideoSubscribed(video.VideoId);
                }
                return video;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"获取视频详情出错: {ex.Message}");
                return null;
            }
        }



        /// <summary>
        /// 订阅视频
        /// 将视频添加到订阅列表并保存到本地
        /// </summary>
        /// <param name="video">要订阅的视频对象</param>
        /// <returns>订阅是否成功</returns>
        public async Task<bool> SubscribeVideoAsync(VideoViewModel video)
        {
            try
            {
                // 检查是否已订阅
                if (IsVideoSubscribed(video.VideoId))
                {
                    // 调用下载视频方法
                    await DownloadVideoAsync(video);
                    return true;
                }
                    

                // 标记为已订阅
                video.IsSubscribed = true;
                
                // 添加到订阅集合
                _subscribedVideos.Add(video);
                
                // 保存订阅信息
                await SaveSubscribedVideosAsync();
                
                // 调用下载视频方法
                await DownloadVideoAsync(video);
                
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"订阅视频出错: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 下载视频
        /// 使用HttpClient下载视频文件并更新下载进度
        /// </summary>
        /// <param name="video">要下载的视频</param>
        /// <returns>下载是否成功</returns>
        /// <remarks>
        /// 跨平台实现的复杂性：
        /// 1. Android平台使用应用专属的外部存储目录，确保文件在应用卸载时被清理。
        /// 2. iOS/Windows平台使用默认的下载目录，确保文件在应用数据目录下。
        /// 3. 不同平台的目录结构和权限管理不同，需要分别处理。
        /// 
        /// 异步操作：
        /// 1. 使用异步方法下载文件，避免阻塞UI线程。
        /// 2. 使用ConfigureAwait(false)避免不必要的上下文切换，提高性能。
        /// 
        /// 线程安全：
        /// 1. 使用同步模式创建文件流，避免异步写入导致的文件损坏。
        /// 2. 使用Device.BeginInvokeOnMainThread确保UI更新在主线程执行。
        /// 
        /// 异常处理策略：
        /// 1. 捕获所有异常，记录日志，并返回失败状态。
        /// 2. 确保资源释放，避免内存泄漏。
        /// </remarks>
        public async Task<bool> DownloadVideoAsync(VideoViewModel video)
        {
            try
            {
                // 准备下载参数
                var parameters = new Dictionary<string, string> { { "id", video.VideoId.ToString() } };
                var downloadUrl = ApiConfig.Video.DownloadVideo.GetFullUrl(parameters);

                // 平台特定的下载目录选择
                string downloadDir;
                string localFilePath;

                #if ANDROID
                // 对于 Android，使用应用专属的外部存储目录
                var context = Android.App.Application.Context;
                var externalFilesDir = context.GetExternalFilesDir(null);
                
                if (externalFilesDir != null)
                {
                    // 使用应用专属的外部存储目录下的 Download 文件夹
                    downloadDir = Path.Combine(externalFilesDir.AbsolutePath, "Download");
                }
                else
                {
                    // 如果外部存储不可用，回退到应用内部存储
                    downloadDir = Path.Combine(FileSystem.AppDataDirectory, "Downloads");
                }
                
                // 生成本地文件名
                string localFileName = $"{video.VideoId}.mp4";
                localFilePath = Path.Combine(downloadDir, localFileName);

                // 确保目录存在
                Directory.CreateDirectory(downloadDir);

                System.Diagnostics.Debug.WriteLine($"Android 下载路径: {localFilePath}");
                #else
                // 对于其他平台（iOS/Windows），使用默认下载目录
                downloadDir = Path.Combine(FileSystem.AppDataDirectory, "Downloads");
                Directory.CreateDirectory(downloadDir);

                // 生成本地文件名
                string localFileName = $"{video.VideoId}.mp4";
                localFilePath = Path.Combine(downloadDir, localFileName);
                #endif

                // 标记开始下载
                video.IsDownloading = true;
                video.DownloadProgress = 0;
                var _httpClient = HttpClientFactory.GetClient();
                // 下载文件
                using (var response = await _httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead))
                {
                    response.EnsureSuccessStatusCode();
                    var totalBytes = response.Content.Headers.ContentLength ?? -1L;

                    Stream contentStream = null;
                    FileStream fileStream = null;

                    try
                    {
                        contentStream = await response.Content.ReadAsStreamAsync()
                                              .ConfigureAwait(false);

                        // 使用同步模式创建文件流
                        fileStream = new FileStream(
                            localFilePath,
                            FileMode.Create,
                            FileAccess.Write,
                            FileShare.None,
                            bufferSize: 8192,
                            useAsync: false // 关键：禁用异步模式
                        );

                        var buffer = new byte[8192];
                        int bytesRead;
                        // 原有的读写操作
                        var totalRead = 0L;
                        

                        while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)
                                                              .ConfigureAwait(false)) > 0)
                        {
                            fileStream.Write(buffer, 0, bytesRead); // 同步写入

                            totalRead += bytesRead;
                            if (totalBytes > 0)
                            {
                                // 更新进度需回到主线程（如 UI 操作）
                                Device.BeginInvokeOnMainThread(() =>
                                    video.DownloadProgress = (double)totalRead / totalBytes * 100
                                );
                                
                            }
                        }
                    }
                    finally
                    {
                        contentStream?.Dispose();
                        fileStream?.Dispose();
                    }
                }

                // 下载完成，更新视频信息
                video.IsDownloading = false;
                video.DownloadProgress = 100;
                video.LocalFilePath = localFilePath;

                // 更新订阅列表
                await SaveSubscribedVideosAsync();

                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"下载视频出错: {ex.Message}");
                video.IsDownloading = false;
                return false;
            }
        }

        /// <summary>
        /// 取消订阅视频
        /// 从订阅列表中移除视频并更新本地存储
        /// </summary>
        /// <param name="videoId">要取消订阅的视频ID</param>
        /// <returns>取消订阅是否成功</returns>
        public async Task<bool> UnsubscribeVideoAsync(long videoId)
        {
            try
            {
                // 查找要取消订阅的视频
                var video = _subscribedVideos.FirstOrDefault(v => v.VideoId == videoId);
                if (video != null)
                {
                    // 从集合中移除
                    _subscribedVideos.Remove(video);
                    
                    // 保存更新后的订阅信息
                    await SaveSubscribedVideosAsync();
                    
                    // 如果有本地文件，删除它
                    if (!string.IsNullOrEmpty(video.LocalFilePath) && File.Exists(video.LocalFilePath))
                    {
                        File.Delete(video.LocalFilePath);
                    }
                    
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"取消订阅视频出错: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 检查视频是否已订阅
        /// </summary>
        /// <param name="videoId">视频ID</param>
        /// <returns>是否已订阅</returns>
        public bool IsVideoSubscribed(long videoId)
        {
            return _subscribedVideos.Any(v => v.VideoId == videoId);
        }

        /// <summary>
        /// 搜索已订阅的视频
        /// 在本地订阅列表中搜索匹配的视频
        /// </summary>
        /// <param name="query">搜索关键词</param>
        /// <returns>匹配的视频列表</returns>
        public List<VideoViewModel> SearchSubscribedVideos(string query)
        {
            if (string.IsNullOrWhiteSpace(query))
                return _subscribedVideos.ToList();
                
            return _subscribedVideos
                .Where(v => v.Title.Contains(query, StringComparison.OrdinalIgnoreCase))
                .ToList();
        }

        /// <summary>
        /// 对已订阅视频进行排序
        /// 根据指定的排序选项对视频列表进行排序
        /// </summary>
        /// <param name="sortBy">排序选项</param>
        /// <returns>排序后的视频列表</returns>
        public List<VideoViewModel> SortSubscribedVideos(VideoSortOption sortBy)
        {
            switch (sortBy)
            {
                case VideoSortOption.TitleAscending:
                    return _subscribedVideos.OrderBy(v => v.Title).ToList();
                case VideoSortOption.TitleDescending:
                    return _subscribedVideos.OrderByDescending(v => v.Title).ToList();
                case VideoSortOption.DateAscending:
                    return _subscribedVideos.OrderBy(v => v.CreatedDate).ToList();
                case VideoSortOption.DateDescending:
                    return _subscribedVideos.OrderByDescending(v => v.CreatedDate).ToList();
                default:
                    return _subscribedVideos.ToList();
            }
        }

        /// <summary>
        /// 加载已订阅视频
        /// 从本地存储中读取订阅信息
        /// </summary>
        private void LoadSubscribedVideos()
        {
            try
            {
                if (File.Exists(_subscriptionsFilePath))
                {
                    string json = File.ReadAllText(_subscriptionsFilePath);
                    var videos = JsonSerializer.Deserialize<List<VideoViewModel>>(json);
                    if (videos != null)
                    {
                        _subscribedVideos = new ObservableCollection<VideoViewModel>(videos);
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载已订阅视频出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 保存已订阅视频
        /// 将订阅信息保存到本地存储
        /// </summary>
        private async Task SaveSubscribedVideosAsync()
        {
            try
            {
                string json = JsonSerializer.Serialize(_subscribedVideos.ToList());
                await File.WriteAllTextAsync(_subscriptionsFilePath, json);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存已订阅视频出错: {ex.Message}");
            }
        }
    }

    /// <summary>
    /// 视频排序选项枚举
    /// 定义了可用的视频排序方式
    /// </summary>
    public enum VideoSortOption
    {
        /// <summary>
        /// 按标题升序排序
        /// </summary>
        TitleAscending,
        
        /// <summary>
        /// 按标题降序排序
        /// </summary>
        TitleDescending,
        
        /// <summary>
        /// 按日期升序排序
        /// </summary>
        DateAscending,
        
        /// <summary>
        /// 按日期降序排序
        /// </summary>
        DateDescending
    }
}